#!/usr/bin/env python
# encoding: utf-8
"""
vmfileproxy.py

Created by Clifford Meece on 2008-04-27.
Copyright (c) 2008 abeedoo.com. All rights reserved.
"""
# immediate
#############
# create mac package
# create initial variable setup instal script for mac
# fix plist file for correct icons
# change defaults command, raise errors
# todo make icons better
# todo create windows installer
# add password save logic
# unity mode applescripts
# figure out licencing etc
# add shared folder id num option




import os
import sys
import socket
import wx
import re
import fileinput
from pyparsing import *
import datetime,time
import logging
import struct
import hmac
import hashlib

logging.basicConfig(level=logging.DEBUG,
                    format='%(name)s: %(message)s',
                    )

DEBUG = True

class HiddenFrame(wx.Frame):
    def __init__(self, title = "vfileproxy"):
        self.dirname=''
        wx.Frame.__init__(self,None,-1, title)
        # Setting up the menu.
        MenuBar = wx.MenuBar()
        FileMenu = wx.Menu()
        item = FileMenu.Append(wx.ID_EXIT, text = "&Exit")
        self.Bind(wx.EVT_MENU, self.OnQuit, item)
        item = FileMenu.Append(wx.ID_ANY, text = "&Open")
        self.Bind(wx.EVT_MENU, self.OnOpen, item)
        item = FileMenu.Append(wx.ID_PREFERENCES, "&Preferences")
        self.Bind(wx.EVT_MENU, self.OnPrefs, item)
        MenuBar.Append(FileMenu, "&File")
        HelpMenu = wx.Menu()
        item = HelpMenu.Append(wx.ID_HELP, "Test &Help",
                        "Help for this simple test")
        self.Bind(wx.EVT_MENU, self.OnHelp, item)
        ## this gets put in the App menu on OS-X
        item = HelpMenu.Append(wx.ID_ABOUT, "&About",
                        "More information About this program")
        self.Bind(wx.EVT_MENU, self.OnAbout, item)
        MenuBar.Append(HelpMenu, "&Help")
        self.SetMenuBar(MenuBar)

    def OnQuit(self,Event):
        self.Destroy()

    def OnAbout(self, event):
        dlg = wx.MessageDialog(self, "This is a small program to test\n"
                            "the use of menus on Mac, etc.\n",
                        "About Me", wx.OK | wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()

    def OnHelp(self, event):
        dlg = wx.MessageDialog(self, "This would be help\n"
                             "If there was any\n",
                        "vmfileproxy", wx.OK | wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()


    def OnPrefs(self, event):
        pref = PrefDialog(None, -1, 'Preferences')
        pref.Centre(wx.BOTH)
        pref.ShowModal()
        
    def OnOpen(self,e):
        """ Open a file"""
        dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "*.*", wx.OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            self.filename=dlg.GetFilename()
            self.dirname=dlg.GetDirectory()
            app.MacOpenFile(os.path.join(self.dirname, self.filename))
            f.close()
        dlg.Destroy()

class PrefDialog(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title)
        frameSizer= wx.BoxSizer(wx.VERTICAL)
        self.panel = wx.Panel(self, -1)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.nb = wx.Notebook(self.panel)        
        # create the page windows as children of the notebook
        self.generalPage = GeneralPage(self.nb)
        self.updatePage = UpdatePage(self.nb)
        self.connectionPage = ConnectionPage(self.nb)
        self.licencePage = LicencePage(self.nb)
        # add the pages to the notebook with the label to show on the tab
        self.nb.AddPage(self.generalPage, "General")
        self.nb.AddPage(self.connectionPage, "Connection")
        self.nb.AddPage(self.updatePage, "Updates")
        self.nb.AddPage(self.licencePage, "Licence")
        sizer.Add(self.nb, 1, wx.EXPAND|wx.TOP|wx.BOTTOM|wx.LEFT|wx.RIGHT,10)
        self.panel.SetAutoLayout(1)
        self.panel.SetSizer(sizer)
        self.panel.Layout()
        frameSizer.Add(self.panel,1,wx.EXPAND|wx.TOP|wx.BOTTOM|wx.LEFT|wx.RIGHT,10)
        self.SetAutoLayout(1)
        self.SetSizerAndFit(frameSizer)
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        
    def OnClose(self,e):
        logger.debug('pref close')
        logger.debug("port is %s",self.connectionPage.txtPort.GetValue())
        self.Destroy()


class GeneralPage(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        t = wx.StaticText(self, -1, "Specify the default VM to use:")
        text = readDefaults("com.vmware.fusion","VMFavoritesListDefaults")
        logger.debug("defaults output: %s", text)
        vm_paths = list(str(x).strip('"').rstrip("\n") for x in re.findall('".*"', text))
        vm_names = []
        for vm in vm_paths:
            logger.debug("vm path: %s", vm)
            vm_name = vm.split("/")[-1]
            vm_name = re.sub('\.vmwarevm','',vm_name)
            vm_names.append(vm_name)
        self.defaultVmChoice = ValueChoice(self, -1)
        self.defaultVmChoice.SetItems((vm_names,vm_paths))
        defaultVmPath = readDefaults("com.abeedoo.vmfileproxy","defaultVmPath").rstrip("\n")
        logger.debug("default VM path: %s",defaultVmPath)
        self.defaultVmChoice.SetValue(defaultVmPath)
        self.defaultVmChoice.Bind(wx.EVT_CHOICE, self.OnSelectVM)

        self.autostartCheckBox = wx.CheckBox(self, -1 ,'Automatically start target VM')
        self.autostartCheckBox.Bind(wx.EVT_CHECKBOX, self.OnCheckAutostart)
        autostart = parseBoolString(readDefaults("com.abeedoo.vmfileproxy","autostart"))
        self.autostartCheckBox.SetValue(autostart)

        self.unityModeCheckBox = wx.CheckBox(self, -1 ,'Put Vm in Unity Mode')
        self.unityModeCheckBox.Bind(wx.EVT_CHECKBOX, self.OnCheckUnityMode)
        unityMode = parseBoolString(readDefaults("com.abeedoo.vmfileproxy","unityMode"))
        self.unityModeCheckBox.SetValue(unityMode)
        
        self.debugModeCheckBox = wx.CheckBox(self, -1 ,'Debug mode')
        self.debugModeCheckBox.Bind(wx.EVT_CHECKBOX, self.OnCheckDebug)
        debugMode = parseBoolString(readDefaults("com.abeedoo.vmfileproxy","debugMode"))
        self.debugModeCheckBox.SetValue(debugMode)

        sizer=wx.BoxSizer(wx.VERTICAL)
        sizer.Add(t,1,wx.TOP|wx.LEFT|wx.RIGHT,10)
        sizer.Add(self.defaultVmChoice,1,wx.TOP|wx.LEFT|wx.RIGHT,10)
        sizer.Add(self.autostartCheckBox,1,wx.TOP|wx.LEFT|wx.RIGHT,10)
        sizer.Add(self.unityModeCheckBox,1,wx.TOP|wx.LEFT|wx.RIGHT,10)
        sizer.Add(self.debugModeCheckBox,1,wx.TOP|wx.LEFT|wx.RIGHT,10)
        #Layout sizers
        self.SetAutoLayout(1)
        self.SetSizer(sizer)
        self.Layout()
    def OnSelectVM(self, event):
        command = "defaults write com.abeedoo.vmfileproxy defaultVmPath " + "\"" + self.defaultVmChoice.GetValue() + "\""
        os.system(command)
        command = "defaults write com.abeedoo.vmfileproxy defaultVmName " + "\"" + self.defaultVmChoice.GetName() + "\""
        os.system(command)
    def OnCheckDebug(self, event):
        logger.debug("debug checkbox clicked")
        logger.debug("debug checkbox status: %s", str(self.debugModeCheckBox.GetValue()))
        value = str(self.debugModeCheckBox.GetValue())
        writeDefaults("com.abeedoo.vmfileproxy","debugMode",value)
    def OnCheckAutostart(self, event):
        logger.debug("autostart checkbox clicked")
        logger.debug("autostart checkbox status: %s", str(self.autostartCheckBox.GetValue()))
        value = str(self.autostartCheckBox.GetValue())
        writeDefaults("com.abeedoo.vmfileproxy","autostart",value)
    def OnCheckUnityMode(self, event):
        logger.debug("unityMode checkbox clicked")
        logger.debug("unityMode checkbox status: %s", str(self.unityModeCheckBox.GetValue()))
        value = str(self.unityModeCheckBox.GetValue())
        writeDefaults("com.abeedoo.vmfileproxy","unityMode",value)    

class ConnectionPage(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        # port
        self.lblPort = wx.StaticText(self, -1, "Port :")
        self.txtPort = wx.TextCtrl(self, -1)
        self.txtPort.SetValue(readDefaults("com.abeedoo.vmfileproxy","port"))
        # use static IP?
        self.chkStaticIP = wx.CheckBox(self, -1,'Use static IP?')
        self.chkStaticIP.Bind(wx.EVT_CHECKBOX, self.OnCheckStatic)
        blnStaticIP = parseBoolString(readDefaults("com.abeedoo.vmfileproxy","useStaticIP"))
        self.chkStaticIP.SetValue(blnStaticIP)
        self.lblIP = wx.StaticText(self, -1, "IP address or hostname :")
        self.txtIP = wx.TextCtrl(self, -1, name = "IP")
        if blnStaticIP:
            self.txtIP.Enable()
            self.lblIP.Enable()
        else:
            self.txtIP.Enable(False)
            self.lblIP.Enable(False)
        # use password?
        self.chkPassword = wx.CheckBox(self, -1,'Use password')
        self.chkPassword.Bind(wx.EVT_CHECKBOX, self.OnCheckPassword)
        blnUsePassword = parseBoolString(readDefaults("com.abeedoo.vmfileproxy","usePassword"))
        self.chkPassword.SetValue(blnUsePassword)
        self.lblPassword = wx.StaticText(self, -1, "Password :")
        self.txtPassword = wx.TextCtrl(self, -1, name = "password",style=wx.TE_PASSWORD)
        # password confirmation
        self.lblPasswordConfirm = wx.StaticText(self, -1, "Password Confirm:")
        self.txtPasswordConfirm = wx.TextCtrl(self, -1, name = "confirm",style=wx.TE_PASSWORD)
        if blnUsePassword:
            self.txtPassword.Enable()
            self.lblPassword.Enable()
            self.txtPasswordConfirm.Enable()
            self.lblPasswordConfirm.Enable()
        else:
            self.txtPassword.Enable(False)
            self.lblPassword.Enable(False)
            self.txtPasswordConfirm.Enable(False)
            self.lblPasswordConfirm.Enable(False)
        # Save password
        sizer = wx.FlexGridSizer(7,2)
        sizer.Add(self.lblPort,0,wx.ALL,10)
        sizer.Add(self.txtPort,0,wx.ALL,10)
        sizer.Add(self.chkStaticIP,0,wx.ALL,10)
        sizer.Add(wx.StaticText(self, -1, ''), 0, wx.EXPAND|wx.ALL,10)
        sizer.Add(self.lblIP,0,wx.LEFT,30)
        sizer.Add(self.txtIP,0,wx.LEFT,10)
        sizer.Add(self.chkPassword,0,wx.ALL,10)
        sizer.Add(wx.StaticText(self, -1, ''), 0, wx.EXPAND|wx.ALL,10)
        sizer.Add(self.lblPassword,0,wx.LEFT,30)
        sizer.Add(self.txtPassword,0,wx.LEFT,10)
        sizer.Add(self.lblPasswordConfirm,0,wx.LEFT,30)
        sizer.Add(self.txtPasswordConfirm,0,wx.LEFT,10)
        sizer.Add(wx.StaticText(self, -1, ''), 0, wx.EXPAND|wx.ALL,10)
        sizer.Add(wx.StaticText(self, -1, ''), 0, wx.EXPAND|wx.ALL,10)
        self.SetAutoLayout(1)
        self.SetSizer(sizer)
        self.Layout()
    def OnCheckStatic(self, event):
        logger.debug("StaticIP checkbox clicked")
        logger.debug("StaticIP checkbox status: %s", str(self.chkStaticIP.GetValue()))
        bln = self.chkStaticIP.GetValue()
        writeDefaults("com.abeedoo.vmfileproxy","useStaticIP",str(bln))
        if not bln:
            self.lblIP.Enable(False)
            self.txtIP.Enable(False)
        else:
            self.lblIP.Enable()
            self.txtIP.Enable()
    def OnCheckPassword(self, event):
        logger.debug("Use Password checkbox clicked")
        logger.debug("Use Password checkbox status: %s", str(self.chkPassword.GetValue()))
        bln = self.chkPassword.GetValue()
        writeDefaults("com.abeedoo.vmfileproxy","usePassword",str(bln))
        if not bln:
            self.txtPassword.Enable(False)
            self.lblPassword.Enable(False)
            self.txtPasswordConfirm.Enable(False)
            self.lblPasswordConfirm.Enable(False)
        else:
            self.txtPassword.Enable()
            self.lblPassword.Enable()
            self.txtPasswordConfirm.Enable()
            self.lblPasswordConfirm.Enable()

class UpdatePage(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        t = wx.StaticText(self, -1, "This is a PageTwo object", (40,40))
        
class LicencePage(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        t = wx.StaticText(self, -1, "This is a PageThree object", (60,60))

class ValueChoice(wx.Choice):
   def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
       size=wx.DefaultSize, style=0,
       validator=wx.DefaultValidator, name=wx.ChoiceNameStr):
       wx.Choice.__init__(self,parent,id,pos,size,('',),style,validator,name)
       self.valueLU = {}
       self.Enable(False)

   def SetItems(self, iv): 
       """
       iv - a sequence of two sequences.
           iv[0] is a sequence of the names that appear in the widget
           iv[1] is a sequence of the values corresponding to the name
       """       
       wx.Choice.Clear(self)
       if len(iv[0]) == 0:
           self.Enable(False)
           self.valueLU = {}
       else:
           self.Enable(True)
           self.Items = iv[0]
           self.values = iv[1]
           self.Selection = 0
           self.valueLU = dict(zip(self.values, range(len(self.values))))  
           logger.debug("valueLU is: %s",repr(self.valueLU))     

   def GetValue(self):
       return self.values[self.Selection]
       
   def GetName(self):
       return self.Items[self.Selection]

   def SetValue(self, value):
       s = self.valueLU[value]
       if s is not None:
           self.Selection = s

   def Clear(self):
       self.Selection = 0


class MyApp(wx.App):
    def OnInit(self):
        self.frame = HiddenFrame()
        #frame.Show()
        
        for f in  sys.argv[1:]:
            self.MacOpenFile(f)
        return True

    def OpenFileMessage(self, filename):
        dlg = wx.MessageDialog(None,
                               "This app was just asked to open:\n%s\n"%filename,
                               "File Dropped",
                               wx.OK|wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()

    def MacOpenFile(self, filename):
        #self.OpenFileMessage(filename)
        # get default vm location
        stdout_handle = os.popen("defaults read com.abeedoo.vmfileproxy defaultVmPath", "r")
        defaultVmPath = stdout_handle.read().rstrip("\n")
        stdout_handle = os.popen("defaults read com.abeedoo.vmfileproxy defaultVmName", "r")
        defaultVmName = stdout_handle.read().rstrip("\n")
        # get vmx file location
        defaultVmConfigFileList = dirEntries(defaultVmPath, False, '.*\.vmx$')
        logger.debug("default Vmx files: %s",repr(defaultVmConfigFileList))
        # if more than one config file, throw an error
        if len(defaultVmConfigFileList) == 1:
            defaultVmConfigFile = defaultVmConfigFileList[0]
        else:
            dlg = wx.MessageDialog(self.frame, "More than one vmx file found in VM directory.\n"
                                "Please correct and try again.\n",
                            "Multiple VMX files", wx.OK | wx.ICON_INFORMATION)
            dlg.ShowModal()
            dlg.Destroy()
            self.Destroy()
            sys.exit(1)
        # find out shared file location
        # right now assume it is shared folder 0
        sharedFoldersEnabled = False
        hostPath = ''
        guestName = ''
        for line in fileinput.input(defaultVmConfigFile):
            m = re.search("sharedFolder0\.enabled = \"TRUE\"",line)
            if m:
                logger.debug("Found shared Folders enabled line")
                sharedFoldersEnabled = True
            m = re.search("sharedFolder0\.hostPath = \"(.*)\"",line)
            if m:
                logger.debug("Found hostPath line")
                hostPath = m.group(1)
            m = re.search("sharedFolder0\.guestName = \"(.*)\"",line)
            if m:
                logger.debug("Found guestName line")
                guestName = m.group(1)
            m = re.search("ethernet0.generatedAddress = \"(.*)\"",line)
            if m:
                logger.debug("Found macAddress line")
                guestMacAddress = m.group(1)

        if sharedFoldersEnabled:
            logger.debug("original filename = %s",filename)
            logger.debug("Shared folder path = %s",hostPath)
            logger.debug("Guest root = %s",guestName)
            logger.debug("MAC address = %s",guestMacAddress)
            # replace shared path with guest path
            # fixme, this will differ for linux
            guestPath = r'\\.host/Shared Folders/' + guestName
            guestPath = filename.replace(hostPath, guestPath)
            logger.debug("Guest path will be: %s", guestPath)
        else:
            dlg = wx.MessageDialog(self.frame, "Shared folders must be enabled for the default VM\n"
                                "specified in the vmfileproxy preferences dialog.\n"
                                "Please correct and try again.\n",
                            "Shared Folders unavailable", wx.OK | wx.ICON_INFORMATION)
            dlg.ShowModal()
            dlg.Destroy()
            self.Destroy()
            sys.exit(1)
        # Is Vm running? check /var/run/vmware
        # build list of all vmx files
        fileList = dirEntries(r'/var/run/vmware', True, '^configFile$')
        # slick way of eliminating dulicates
        uniq_list=dict(zip(fileList,fileList)).keys()
        logger.debug("running config files: %s",repr(uniq_list))
        # is default vm in that list?
        if len(uniq_list) > 0:
            for running_config in uniq_list:
                if defaultVmConfigFile == running_config:
                    # vm is on
                    logger.debug("%s is already running", defaultVmName)
                    break
                else:
                    # vm is off, start it up
                    logger.debug("starting vm %s",defaultVmName)
                    command = "open \"" + defaultVmConfigFile + "\"" 
                    os.system(command)
                    break
        else:
            # vm is off, start it up
            logger.debug("starting vm %s",defaultVmName)
            command = "open \"" + defaultVmConfigFile + "\"" 
            os.system(command)
        # todo Put vm in unity mode(use apple script sample)
        #
        #
        # get the guest ip address
        infile = open("/var/db/vmware/vmnet-dhcpd-vmnet8.leases", "r" )
        # todo get items from vmnet1 too
        leasestring = infile.read()
        LBRACE,RBRACE,SEMI,QUOTE = map(Suppress,'{};"')
        ipAddress = Combine(Word(nums) + ('.' + Word(nums))*3)
        hexint = Word(hexnums,exact=2)
        macAddress = Combine(hexint + (':'+hexint)*5)
        uid = Combine(hexint + (':'+hexint)*6)
        hdwType = Word(alphanums)
        clientHostname = Word(alphanums + "-")
        yyyymmdd = Combine((Word(nums,exact=4)|Word(nums,exact=2))+
                            ('/'+Word(nums,exact=2))*2)
        hhmmss = Combine(Word(nums,exact=2)+(':'+Word(nums,exact=2))*2)
        dateRef = oneOf(list("0123456"))("weekday") + yyyymmdd("date") + \
                                                                hhmmss("time")
        dateRef.setParseAction(utcToLocalTime)
        startsStmt = "starts" + dateRef + SEMI
        endsStmt = "ends" + (dateRef | "never") + SEMI
        hdwStmt = "hardware" + hdwType("type") + macAddress("mac") + SEMI
        uidStmt = "uid" + uid("uid") + SEMI
        hostnameStmt = "client-hostname" + QuotedString('"')("hostname") + SEMI 
        leaseStatement = startsStmt | endsStmt | hdwStmt | uidStmt | hostnameStmt
        leaseDef = "lease" + ipAddress("ipaddress") + LBRACE + \
                                    Dict(ZeroOrMore(Group(leaseStatement))) + RBRACE
        ipLU={}
        for lease in leaseDef.searchString(leasestring):
            logger.debug("%s->%s",lease.ipaddress,lease.hardware.mac)
            ipLU[lease.hardware.mac] = lease.ipaddress
        logger.debug("Guest mac is: %s",guestMacAddress)
        guestIP = ipLU[guestMacAddress]
        logger.debug("Guest IP is: %s",guestIP)
        
        # Now connect to Host
        # Send the data
        port = int(readDefaults("com.abeedoo.vmfileproxy","port"))
        logger.debug('connecting to server %s,%s',guestIP,port)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((guestIP, port))
        challenge = s.recv(16)
        logger.debug('Challenge received: "%s"', repr(challenge))
        myhmac = hmac.new('password',challenge,hashlib.sha1)
        auth=myhmac.hexdigest()
        logger.debug('sending auth: "%s"', auth)
        auth=auth + "\n"
        s.send(auth)
        auth_response = s.recv(7)
        if auth_response == 'SUCCESS':
            logger.debug('sending path: "%s"', guestPath)
            guestPath=guestPath + "\n"
            s.send(guestPath)
            path_response = s.recv(7)
            if path_response == 'FAILURE':
                dlg = wx.MessageDialog(self.frame, "There was a problem on the VM Guest.\n"
                                    "\nThe VM Guest said:\n\n" + response + "\n",
                                "Error in the VM guest", wx.OK | wx.ICON_INFORMATION)
                dlg.ShowModal()
                dlg.Destroy()
            s.close()
            self.Destroy()
            sys.exit(1)
        else:
            dlg = wx.MessageDialog(self.frame, "Authentication failed.\n"
                                    "\nPlease check password settings\n\n",
                                "Authentication Failed", wx.OK | wx.ICON_INFORMATION)
            dlg.ShowModal()
            dlg.Destroy()
        logger.debug('closing socket')
        s.close()
        self.Destroy()
        sys.exit(1)

def readDefaults(domain,key):
    command = "defaults read " + domain + " " + key
    logger.debug("command to be executed is: %s", command)
    stdout_handle = os.popen(command, "r")
    value = stdout_handle.read()
    return value

def writeDefaults(domain, key, value):
    command = "defaults write " + domain + " " + key + " \"" + value + "\""
    logger.debug("command to be executed is: %s", command)
    return os.system(command)



def utcToLocalTime(tokens):
    utctime = datetime.datetime.strptime("%(date)s %(time)s" % tokens,
                                                    "%Y/%m/%d %H:%M:%S")
    localtime = utctime-datetime.timedelta(0,time.timezone,0)
    tokens["utcdate"],tokens["utctime"] = tokens["date"],tokens["time"]
    tokens["localdate"],tokens["localtime"] = str(localtime).split()
    del tokens["date"]
    del tokens["time"]

def dirEntries(dir_name, subdir, regexp):
    '''Return a list of file names found in directory 'dir_name'
    If 'subdir' is True, recursively access subdirectories under 'dir_name'.
    Additional arguments, if any, are file extensions to match filenames. Matched
        file names are added to the list.
    If there are no additional arguments, all files found in the directory are
        added to the list.
    Example usage: fileList = dirEntries(r'H:\TEMP', False, 'txt', 'py')
        Only files with 'txt' and 'py' extensions will be added to the list.
    Example usage: fileList = dirEntries(r'H:\TEMP', True)
        All files and all the files in subdirectories under H:\TEMP will be added
        to the list.
    '''
    fileList = []
    for file in os.listdir(dir_name):
        dirfile = os.path.join(dir_name, file)
        if os.path.isfile(dirfile):
            if not regexp:
                fileList.append(dirfile)
            else:
                if re.search(regexp, os.path.basename(dirfile)):
                    fileList.append(os.path.realpath(dirfile))
        # recursively access file names in subdirectories
        elif os.path.isdir(dirfile) and subdir:
            #print "Accessing directory:", dirfile
            fileList.extend(dirEntries(dirfile, subdir, regexp))
    return fileList


#assume a socket disconnect (data returned is empty string) means  all data was #done being sent.
def recv_basic(the_socket):
    total_data=[]
    while True:
        data = the_socket.recv(8192)
        if not data: break
        total_data.append(data)
    return ''.join(total_data)

#    self.rx_buf is set to "" in the initialisation
#    self.sock is the socket

#def recv_line(self):
#    message = None
#    while 1:
#        pos = self.rx_buf.find("\r\n")
#        if pos >= 0:
#            message = self.rx_buf[:pos]
#            self.rx_buf = self.rx_buf[pos+2:]
#            break
#        try:
#            rx = self.sock.recv(4096)
#        except socket.error, e:
#            self.sock = None
#            raise ServerNetworkException(e)
#        if len(rx) == 0:
#            self.sock = None
#            raise ServerDisconnectedException()
#        self.rx_buf += rx
#    return message

def recv_timeout(the_socket,timeout=2):
    the_socket.setblocking(0)
    total_data=[];data='';begin=time.time()
    while 1:
        #if you got some data, then break after wait sec
        if total_data and time.time()-begin>timeout:
            break
        #if you got no data at all, wait a little longer
        elif time.time()-begin>timeout*2:
            break
        try:
            data=the_socket.recv(8192)
            if data:
                total_data.append(data)
                begin=time.time()
            else:
                time.sleep(0.1)
        except:
            pass
    return ''.join(total_data)

End='ENDOFTRANSMISSION'
def recv_end(the_socket):
    total_data=[];data=''
    while True:
            data=the_socket.recv(8192)
            if End in data:
                total_data.append(data[:data.find(End)])
                break
            total_data.append(data)
            if len(total_data)>1:
                #check if end_of_data was split
                last_pair=total_data[-2]+total_data[-1]
                if End in last_pair:
                    total_data[-2]=last_pair[:last_pair.find(End)]
                    total_data.pop()
                    break
    return ''.join(total_data)

def recv_size(the_socket, recv_size=8192):
    #data length is packed into 4 bytes
    total_len=0;total_data=[];size=sys.maxint
    size_data=sock_data=''
    while total_len<size:
        sock_data=the_socket.recv(recv_size)
        if not total_data:
            if len(sock_data)>4:
                size_data+=sock_data
                size=struct.unpack('>i', size_data[:4])[0]
                recv_size=size
                if recv_size>524288:recv_size=524288
                total_data.append(size_data[4:])
            else:
                size_data+=sock_data
        else:
            total_data.append(sock_data)
        total_len=sum([len(i) for i in total_data ])
    return ''.join(total_data)

def parseBoolString(theString):
  return (True,False)[theString!="True"]

logger = logging.getLogger('vmfileproxy')
logger.debug('Vmfileproxy starting')

app = MyApp(False)
app.MainLoop()
logger.debug('Vmfileproxy stopping')

